package mediainfo;

import mediainfo.domain.Audio;
import mediainfo.domain.General;
import mediainfo.domain.MovieMetadata;
import mediainfo.domain.Video;
import mediainfo.jna.MediaInfo;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * Information relatives to a movie file.
 *
 * @author Cedrick Lunven (@clunven)</a>
 */
public class MovieMetadataParser {

    /**
     * Singleton pattern, avoid synchronized using static declaration.
     */
    public enum MovieMetadataParserHolder {
        INSTANCE;
        MovieMetadataParser PARSER = new MovieMetadataParser();
    }

    /**
     * Singleton pattern, holder.
     *
     * @return
     */
    public static MovieMetadataParser getInstance() {
        return MovieMetadataParserHolder.INSTANCE.PARSER;
    }

    /**
     * Default Parser.
     */
    private MovieMetadataParser() {
    }

    /**
     * Read Metadata of file
     */
    public MovieMetadata parseFile(String path) {
        return parseFile(new File(path));
    }

    public MovieMetadata parseFile(File file) {
        MediaInfo info = new MediaInfo();
        MovieMetadata mm = new MovieMetadata(file.getAbsolutePath());
        try {
            info.open(file);
            for (General gKey : General.values()) {
                String val = info.get(MediaInfo.StreamKind.General, 0, gKey.getKey(), MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
                if (val != null && !val.isEmpty()) {
                    mm.getGeneralKeys().put(gKey, val);
                }
            }
            int audioCount = info.streamCount(MediaInfo.StreamKind.Audio);
            for (int i = 0; i < audioCount; i++) {
                Map<Audio, String> map = new HashMap<>();
                for (Audio aKey : Audio.values()) {
                    String val = info.get(MediaInfo.StreamKind.Audio, i, aKey.getKey(), MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
                    if (val != null && !val.isEmpty()) {
                        map.put(aKey, val);
                        if (i == 0) {
                            mm.getAudioKeys().put(aKey, val);
                        }
                    }
                }
                mm.getAudioKeysList().add(map);
            }
            int videoCount = info.streamCount(MediaInfo.StreamKind.Video);
            for (int i = 0; i < videoCount; i++) {
                Map<Video, String> map = new HashMap<>();
                for (Video vKey : Video.values()) {
                    String val = info.get(MediaInfo.StreamKind.Video, i, vKey.getKey(), MediaInfo.InfoKind.Text, MediaInfo.InfoKind.Name);
                    if (val != null && !val.isEmpty()) {
                        map.put(vKey, val);
                        if (i == 0) {
                            mm.getVideoKeys().put(vKey, val);
                        }
                    }
                }
                mm.getVideoKeysList().add(map);
            }

        } finally {
            info.close();
        }
        return mm;
    }


}
